<template>
  <!-- 维度分析弹窗 -->
  <el-dialog draggable v-model="visible" title="维度分析" width="540px" :modal="false" :modal-penetrable="true"
    :close-on-press-escape="false" :style="{ opacity: statisticOpacity }">
    <div class="flex flex-col items-center justify-center w-full text-#fff">
      <div class="flex flex-col w-full text-#fff">
        <h3>事故数对比</h3>
        <div class="flex flex-row items-center justify-around w-full text-#fff">
          <div @click="
            getMonthCountList(
              monthCountListCurrent,
              monthCountListCurrentIds
            )
            ">
            当月事故数{{ monthCountListCurrent }}
          </div>
          <div @click="
            getMonthCountList(monthCountListLast, monthCountListLastIds)
            ">
            往年同期事故数{{ monthCountListLast }}
          </div>
        </div>
      </div>
      <div class="flex flex-col w-full text-#fff">
        <h3>事故图</h3>
        <div ref="statisticPieChartRef" class="w-80% h-300px flex items-center justify-center ml-20px"></div>
      </div>
      <div v-show="statisticDialog.showCheck">
        <div class="text-20px text-center my-10px">
          <div>事故形态：{{ statisticDialog.checkPieName }}</div>
          <div>选择展示分析图</div>
        </div>
        <el-checkbox v-model="statisticDialog.checkAll" :indeterminate="statisticDialog.isIndeterminate"
          @change="handleAllChecked">全选</el-checkbox>
        <el-checkbox-group v-model="statisticDialog.checkedCities" @change="handleChecked">
          <el-checkbox v-for="item in PIE_CHART_ITEM" :key="item.type" :label="item.label" :value="item.type">{{
            item.label.slice(5, 10) }}</el-checkbox>
        </el-checkbox-group>
        <el-button class="mt-10px ml-40%" type="primary" @click="handleShowDiagram()">展示分析图</el-button>
      </div>
    </div>
  </el-dialog>

  <!-- 维度分析详情图形弹窗 -->
  <el-drawer :z-index="3" v-model="statisticGraphicalDialog.visible" :show-close="false"
    :title="TYPE_DETAIL_TITLE[type] || ''" direction="ltr" size="25%" :close-on-click-modal="false">
    <template #header>
      <div class="flex flex-row justify-between items-center w-[100%] mt-10px mb-10px button-container">
        <el-button type="primary" @click="handelGraphicalBack">返回</el-button>
        <el-button type="warning" @click="refreshPieCharts">刷新</el-button>
        <el-button type="danger" @click="handleAccident">事故调查</el-button>
        <div class="text-20px text-#fff" @click="closeStatisticGraphicalDialog">
          X
        </div>
      </div>
    </template>
    <!-- 按钮容器 -->
    <div class="flex flex-col items-center">
      <div class="flex flex-row items-center mt-10px mb-10px color-white text-16px">
        <span>{{ timeData.startTime.slice(0, 10) }} </span>
        <span> —— </span>
        <span> {{ timeData.endTime.slice(0, 10) }}</span>
      </div>
    </div>

    <!-- 多饼图容器 -->
    <div class="flex flex-col justify-center items-center mt-10px">
      <div v-for="item in statisticDialog.checkedCities" :key="item">
        <div class="flex flex-col items-center color-white">
          <div class="text-22px">{{ statisticGraphicalTitle(item) }}分析</div>
          <div class="flex flex-row">
            <div :id="item" class="w-[300px] h-[300px]"></div>
            <div v-if="item !== 'Time'" class="text-16px mt-40px font-bold">
              <div v-for="(it, i) in statisticGraphicalName[item]" :key="i" :style="{ color: getColor(i) }">
                <div>
                  <span>—{{ it.name }}</span>
                  <span class="ml-0.1rem">({{ it.value }} ,
                    {{
                      ((it.value / statisticGraphicalNum[item]) * 100).toFixed(
                        2
                      )
                    }}%)</span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </el-drawer>

  <AccidentDialog :modelValue="accidentDialogVisible" @back="accidentDialogClose" :statistic-dialog="statisticDialog"
    :time-data="timeData" />

  <PiechartsLists ref="pieChartsRef" @close="statisticGraphicalDialog.visible = true" />
  <!-- 事故数比对弹窗 -->
  <MonthCountIds v-model:visible="monthCountDialog.visible" :listData="monthCountDialog.listData"
    @close="closeMonthCountDialog" />
</template>

<script setup lang="ts">
import AccidentDialog from "./accidentDialog.vue";
import MonthCountIds from "./monthCountIds.vue"
import { PIE_CHART_ITEM, TYPE_DETAIL_TITLE } from "@/const/home";
import { useBoolean, useAccidentTableList, useRectangleDialog } from "@/store";
import { getAssets, getColor } from "@/utils";
import * as MapApi from "@/service/api/map";
import { GetPieChartsDatas } from "@/service/api/SamplInterface";
import { useMouthPoly } from "@/store";
import * as echarts from "echarts";

const changeDimensions = inject("changeDimensions") as (
  dimension: string,
  form: string
) => void;
const worker = new Worker(
  new URL("../../../workers/mapDataWorker.ts", import.meta.url),
  { type: "module" }
);

interface WorkerResponse {
  type: "batch" | "complete";
  data: Array<{ position: string; image: string }> | number;
}

interface Props {
  showStatistic: boolean;
  type: string;
  listData: [];
}

const props = defineProps<Props>();
const emit = defineEmits(["update:showStatistic"]);

const mouthPoly = useMouthPoly();
const accidentStore = useAccidentTableList();
const booleanStore = useBoolean();
const { setState } = useRectangleDialog();
const statisticPieChartRef = ref<any>(null);
const pieChartsRef = ref<any>(null);
// 事故数弹窗
const monthCountDialog = reactive({
  visible: false,
  listData: [],
})
//维度分析弹窗
const statisticDialog = reactive<any>({
  showCheck: false,
  data: [],
  checkPieName: "",
  checkAll: true,
  isIndeterminate: false,
  checkedCities: PIE_CHART_ITEM.map((item) => item.type),
  zIndex: 0, //弹窗层级，当为0得时候且showStatistic为false时，展示两侧面板
});
//维度分析图形详情弹窗
const statisticGraphicalDialog = reactive<any>({
  visible: false,
  data: [],
  checkPieName: "",
  checkAll: true,
  isIndeterminate: false,
});
//维度分析饼状图名称数据
const statisticGraphicalName = reactive<any>({
  Form: [],
  IsolationFacility: [],
  Weather: [],
  Pavement: [],
  Vehicle: [],
  Age: [],
  Time: [],
});
//维度分析饼状图数量数据
const statisticGraphicalNum = reactive<any>({
  Form: [],
  IsolationFacility: [],
  Weather: [],
  Pavement: [],
  Vehicle: [],
  Age: [],
  Time: [],
});
const accidentDialogVisible = ref(false);
const cachedData = ref({});
const timeData = ref<any>([]);

const params = ref<any>({
  pageSize: 10,
  pageNum: 1,
  ids: [],
});

// 维度分析弹窗显示隐藏css控制
const statisticOpacity = computed(() => {
  return monthCountDialog.visible || accidentStore.accidentPageInfoShow || accidentStore.shiGuGaoFaLuDuanShow ? 0 : 1;
})

const statisticGraphicalTitle = computed(() => (type: string) => {
  return (
    PIE_CHART_ITEM.find((item) => item.type === type)?.label.slice(5, 10) || ""
  );
});

const monthCountListCurrent = computed(() => mouthPoly.currentCount);
const monthCountListLast = computed(() => mouthPoly.lastCount);
const monthCountListCurrentIds = computed(() =>
  (mouthPoly.currentData || []).flatMap((item) => item?.ids || [])
);
const monthCountListLastIds = computed(() =>
  (mouthPoly.lastData || []).flatMap((item) => item?.ids || [])
);

const visible = computed({
  get: () => {
    if (props.showStatistic) {
      timeData.value = JSON.parse(localStorage.getItem("dateRange") || "{}");
      pieChartEcharts();
      changeLayer(true);
    }
    if (statisticDialog.zIndex === 0 && !props.showStatistic) {
      booleanStore.setState(true);
      booleanStore.setFooterToolShow(true);
      setState(false, "", []);
    }
    return props.showStatistic;
  },
  set: (val) => emit("update:showStatistic", val),
});

// 监听Web Worker的消息事件，处理分批次返回的数据
worker.addEventListener("message", (e: MessageEvent<WorkerResponse>) => {
  const { type, data } = e.data; // 解析消息类型和数据
  const { draw } = window.cesiumInit;
  if (type === "batch") {
    // 处理分批次返回的数据
    const image = getAssets(data[0].image + "Marker.png"); // 根据数据类型获取对应的图标资源
    draw.addInPolyBillboard(data, image); // 添加标记到地图
  }
});

// 点击事故数比对
const getMonthCountList = async (num, ids) => {
  try {
    if (num === 0) return;
    params.value.pageSize = num;
    params.value.ids = ids;
    const res = await MapApi.GetAccidentPageInfo(params.value);
    monthCountDialog.listData = res.rows;
    monthCountDialog.visible = true;
  } catch (err) {
    console.log(err);
  }
};

// 关闭事故数比对弹窗
const closeMonthCountDialog = () => {
  monthCountDialog.listData = [];
  monthCountDialog.visible = false;
}

// 添加全选/反选逻辑
const handleAllChecked = (val) => {
  statisticDialog.checkedCities = val
    ? PIE_CHART_ITEM.map((item) => item.type)
    : [];
  statisticDialog.isIndeterminate = false;
};

// 添加单个复选框逻辑
const handleChecked = (value) => {
  const checkedCount = value.length;
  statisticDialog.checkAll = checkedCount === PIE_CHART_ITEM.length;
  statisticDialog.isIndeterminate =
    checkedCount > 0 && checkedCount < PIE_CHART_ITEM.length;
};

// 事故调查点击事件
const handleAccident = async () => {
  statisticGraphicalDialog.visible = false;
  accidentDialogVisible.value = true;

  const { draw, mapEvent } = window.cesiumInit;
  if (draw.selectGraphic.length > 0) {
    const { lng, lat } = draw.selectGraphic[0].point;
    mapEvent.flyToPoint({ lng, lat, alt: 500 });
  }
  Promise.all([
    MapApi.GetConstruction(timeData.value),
    MapApi.Getjiankong(),
  ]).then((res) => {
    // 定义数据类型与图标映射关系
    const types = ["construction", "monitor"];
    res.forEach((data, idx) => {
      const type = types[idx];
      // 分批次处理数据并渲染标记点
      worker.postMessage({ data, type });
    });
  });
  changeDimensions("3d", "rectangle-dialog");
};

// 关闭维度分析图形详情弹窗
const closeStatisticGraphicalDialog = () => {
  statisticGraphicalDialog.visible = false;
  visible.value = false;
  statisticDialog.zIndex = 0;
  booleanStore.setState(true);
  booleanStore.setFooterToolShow(true);
  setState(false, "", []);
};

// 图标详情弹窗返回
const handelGraphicalBack = () => {
  statisticGraphicalDialog.visible = false;
  visible.value = true;
  statisticDialog.zIndex = statisticDialog.zIndex - 1;
};

// 事故调查弹窗返回
const accidentDialogClose = () => {
  statisticGraphicalDialog.visible = true;
  accidentDialogVisible.value = false;
};

// 刷新饼图数据
const refreshPieCharts = () => {
  statisticDialog.checkedCities.forEach(async (item) => {
    const data = await generateData(item, statisticDialog.data);
    if (item === "Age") {
      // getChartOptionAge(data.value, item.type);
    } else {
      if (item === "LmzkAndDlwlgl") {
        statisticGraphicalName[item] = data[0].children;
      } else {
        statisticGraphicalName[item] = data;
      }
      nextTick(() => pieChartEchartsData(data, item));
    }
  });
};

// 展示分析图
const handleShowDiagram = () => {
  refreshPieCharts();
  booleanStore.setLeftState(false);
  statisticGraphicalDialog.visible = true;
  visible.value = false;
  statisticDialog.zIndex = statisticDialog.zIndex + 1;
  changeLayer(false);
};

const generateData = async (type: string, ids: []) => {
  try {
    const res = await GetPieChartsDatas(type, ids);

    // 检查数据是否为空
    if (!res || res.length === 0) {
      return [{ name: "无数据", value: 0 }];
    }

    cachedData.value[type] = res;
    return res;
  } catch (err) {
    console.error("获取数据失败:", err);
    return [{ name: "无数据", value: 0 }]; // 返回默认数据
  }
};

const pieChartEchartsData = (date, type) => {
  // 获取容器元素
  const container = document.getElementById(type);
  if (!container) return;

  // 如果已经存在实例，先销毁
  let graphical = echarts.getInstanceByDom(container);
  if (graphical) {
    graphical.dispose();
  }

  // 初始化新的 ECharts 实例
  graphical = echarts.init(container);

  // 设置饼状图的配置项
  graphical.setOption(getChartOption(type, date));

  graphical.on("click", (params) => {
    pieChartsRef.value.fetch(params.data.ids);
    statisticGraphicalDialog.visible = false;
  });
};

const getChartOption = (type, date) => {
  switch (type) {
    case "Time":
      const timeData = date.map((item) => item.name); // 提取时间段
      const timeIds = date.map((item) => item.ids); // 提取对应的ids
      return {
        tooltip: {
          type: "shadow",
          data: timeIds,
          trigger: "axis", // 按轴触发提示框
          axisPointer: {
            type: "line", // 默认为直线，可选为：'line' | 'shadow'
            lineStyle: {
              color: "#ffffff", // 提示框指针颜色
            },
          },
        },
        xAxis: {
          type: "category",
          data: timeData,
          axisLine: {
            lineStyle: {
              color: "#00aaff", // x轴颜色
            },
          },
          axisLabel: {
            textStyle: {
              color: "#ffffff", // x轴字体颜色
              fontSize: 12, // 字体大小
            },
          },
        },
        yAxis: {
          type: "value",
          name: "数量",
          axisLine: {
            lineStyle: {
              color: "#00aaff", // y轴颜色
            },
          },
          axisLabel: {
            textStyle: {
              color: "#ffffff", // y轴字体颜色
              fontSize: 12, // 字体大小
            },
          },
        },
        series: [
          {
            name: "事故数",
            type: "line",
            data: date.map((item) => ({
              value: item.value,
              name: item.name,
              ids: item.ids, // 存储 ids
            })),
            itemStyle: {
              color: "#00BFFF", // 折线颜色
            },
            lineStyle: {
              width: 2, // 折线宽度
            },
            smooth: true, // 是否平滑曲线
          },
        ],
        data: date.map((item) => ({
          value: item.value,
          name: item.name,
          ids: item.ids, // 存储 ids
        })),
      };
    default:
      const num = ref<number>(0);
      date.forEach((it) => {
        num.value += it.value;
      });
      statisticGraphicalNum[type] = num.value;
      return {
        tooltip: { trigger: "item" },
        series: [
          {
            type: "pie",
            label: {
              show: false,
            },
            labelLine: {
              show: false, // 删除指示线
            },
            data: date.map((item, index) => ({
              ...item,
              itemStyle: {
                color: getColor(index),
              },
            })),
          },
        ],
      };
  }
};

const pieChartEcharts = async () => {
  if (!statisticPieChartRef.value) return;
  let chartsInstance = echarts.getInstanceByDom(statisticPieChartRef.value);
  if (chartsInstance) {
    chartsInstance.dispose();
  }

  const data = await generateData("Type", props.listData); // 等待数据加载完成
  chartsInstance = echarts.init(statisticPieChartRef.value);
  chartsInstance.setOption({
    tooltip: { trigger: "item" },
    series: [
      {
        name: "事故形态",
        type: "pie",
        clockWise: false,
        center: ["40%", "50%"],
        radius: ["55%", "65%"],
        data: data.map((item, index) => ({
          ...item,
          itemStyle: {
            color: getColor(index),
          },
        })),
      },
    ],
    title: {
      text: "总数",
      subtext: data.reduce((sum, item) => sum + item.value, 0),
      textStyle: {
        fontSize: 17,
        color: "#fff",
      },
      subtextStyle: {
        fontSize: 20,
        color: "#fff",
      },
      textAlign: "center",
      x: "40%",
      y: "44%",
    },
    elements: [
      {
        type: "image",
        z: 3,
        style: {
          width: 178,
          height: 178,
        },
        left: "center",
        top: "center",
        position: [100, 100],
      },
    ],
  });

  chartsInstance.on("click", (params) => {
    statisticDialog.checkPieName = params.data.name;
    statisticDialog.data = params.data.ids;
    statisticDialog.showCheck = true;
  });
};

const changeLayer = (val: boolean) => {
  if(!window.cesiumInit?.draw) return;
  const { draw, primitiveLoader, map3d } = window.cesiumInit;
  draw.drawLayer && (draw.drawLayer.show = val);
  if (primitiveLoader.heatLayer.length > 0) {
    primitiveLoader.heatLayer.forEach((item) => {
      item.show = val;
    });
  }
  map3d.camera.zoomOut(1);
}
</script>
